package deepbrain.simnetwork.engine;

import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import deepbrain.simnetwork.exception.SimNetworkRuntimeException;
import deepbrain.simnetwork.monitor.MonitorAdapter;
import deepbrain.simnetwork.task.Task;

/**
 * Run tasks in concurrent way
 * 
 * @author Li Yang
 * @create 2009-3-14
 */
public class ConcurrentEngine implements SimEngine {

	private static final int DEFAULT_THREAD_NUM = 10;
	private boolean addingNewTask = false;

	private ExecutorService threadPool;

	public ConcurrentEngine() {
		threadPool = Executors.newFixedThreadPool(DEFAULT_THREAD_NUM);
	}

	public ConcurrentEngine(int threadNum) {
		threadPool = Executors.newFixedThreadPool(threadNum);
	}

	public void runTask(final Task task) {
		addingNewTask = true;
		task.addMonitor(new MonitorAdapter<Task>(true) {
			@Override
			public void onTaskStart(Task task) {
				task.setThreadLocalEngine(ConcurrentEngine.this);
			}
		});
		threadPool.submit(task);
		addingNewTask = false;
	}

	public void runTasks(Collection<Task> tasks) {
		addingNewTask = true;
		for (Task task : tasks)
			runTask(task);
		addingNewTask = false;
	}

	public void stop() {
		threadPool.shutdownNow();
	}

	public void shutdown() {
		while (addingNewTask)
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				throw new SimNetworkRuntimeException(e);
			}
		threadPool.shutdown();
	}

}
